/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rubric;

import java.awt.Color;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JLabel;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
import specifications.Audience;
import specifications.Specifications;
import specifications.YamlObject;

/**
 *
 * @author Jason
 */
public class Rubric implements YamlObject<Rubric> {
    public static final Tag TAG = new Tag("!Rubric");
    private Boolean graded = false;
    private Specifications fsts;
    private ArrayList<ScoredDirective> sourceDirectives;
    private ArrayList<ScoredDirective> targetDirectives;
    private ArrayList<ScoredDirective> productionDirectives;
    private ArrayList<ScoredDirective> environmentDirectives;
    private ArrayList<ScoredDirective> relationshipsDirectives;
//    private Float sourceScore;
    private Float targetScore;
    private Float productionScore;
    private Float environmentScore;
    private Float relationshipsScore;
    private Float totalScore;
    
    public Rubric(){}
    public Rubric(Specifications specs){
        this.fsts = specs;
    }
    @Override
    public void dump(String filename) throws IOException {
        Yaml yaml = new Yaml(CONSTRUCTOR, REPRESENTER);
        FileWriter writer = new FileWriter(filename);
        writer.write(yaml.dumpAs(this, TAG, DumperOptions.FlowStyle.BLOCK));
        writer.close();
    }

    @Override
    public Rubric load(String filename) throws IOException {
        Yaml yaml = new Yaml(CONSTRUCTOR, REPRESENTER);
        FileReader reader = new FileReader(filename);
        Rubric param = yaml.loadAs(reader, Rubric.class);
        reader.close();
        return param;
    }

    private int computePossible(ArrayList<ScoredDirective> dirs){
        int out = 0;
        for (ScoredDirective d : dirs){
            out+= d.getDirective().getPriority();
        }
        return out;
    }
    
    private int computeReceived(ArrayList<ScoredDirective> dirs){
        int out = 0;
        for (ScoredDirective d : dirs){
            Boolean ful = d.getFulfilled();
            if (ful != null){
                if (ful)
                out+= d.getDirective().getPriority();
            }
        }
        
        return out;
    }
    /**
     * @return the fsts
     */
    public Specifications getSpecifications() {
        return fsts;
    }

    /**
     * @param fsts the fsts to set
     */
    public void setSpecifications(Specifications fsts) {
        this.fsts = fsts;
    }

    /**
     * @return the graded
     */
    public Boolean getGraded() {
        return graded;
    }

    /**
     * @param graded the graded to set
     */
    public void setGraded(Boolean graded) {
        this.graded = graded;
    }

    /**
     * @return the sourceDirectives
     */
    public ArrayList<ScoredDirective> getSourceDirectives() {
        return sourceDirectives;
    }

    /**
     * @param sourceDirectives the sourceDirectives to set
     */
    public void setSourceDirectives(ArrayList<ScoredDirective> sourceDirectives) {
        this.sourceDirectives = sourceDirectives;
    }

    /**
     * @return the targetDirectives
     */
    public ArrayList<ScoredDirective> getTargetDirectives() {
        return targetDirectives;
    }

    /**
     * @param targetDirectives the targetDirectives to set
     */
    public void setTargetDirectives(ArrayList<ScoredDirective> targetDirectives) {
        this.targetDirectives = targetDirectives;
    }

    /**
     * @return the productionDirectives
     */
    public ArrayList<ScoredDirective> getProductionDirectives() {
        return productionDirectives;
    }

    /**
     * @param productionDirectives the productionDirectives to set
     */
    public void setProductionDirectives(ArrayList<ScoredDirective> productionDirectives) {
        this.productionDirectives = productionDirectives;
    }

    /**
     * @return the environmentDirectives
     */
    public ArrayList<ScoredDirective> getEnvironmentDirectives() {
        return environmentDirectives;
    }

    /**
     * @param environmentDirectives the environmentDirectives to set
     */
    public void setEnvironmentDirectives(ArrayList<ScoredDirective> environmentDirectives) {
        this.environmentDirectives = environmentDirectives;
    }

    /**
     * @return the relationshipsDirectives
     */
    public ArrayList<ScoredDirective> getRelationshipsDirectives() {
        return relationshipsDirectives;
    }

    /**
     * @param relationshipsDirectives the relationshipsDirectives to set
     */
    public void setRelationshipsDirectives(ArrayList<ScoredDirective> relationshipsDirectives) {
        this.relationshipsDirectives = relationshipsDirectives;
    }

    /**
     * @return the sourceScore
     */
//    public Float getSourceScore() {
//        int poss = computePossible(sourceDirectives);
//        int rec = computeReceived(sourceDirectives);
//        this.sourceScore = (float)rec/poss;
//        return this.sourceScore;
//    }
//
//    /**
//     * @param sourceScore the sourceScore to set
//     */
//    public void setSourceScore(Float sourceScore) {
//        int poss = computePossible(sourceDirectives);
//        int rec = computeReceived(sourceDirectives);
//        this.sourceScore = (float)rec/poss;
//    }

    /**
     * @return the targetScore
     */
    public Float getTargetScore() {
        int poss = computePossible(targetDirectives);
        int rec = computeReceived(targetDirectives);
        this.targetScore = (float)rec/poss;
        return this.targetScore;
    }

    /**
     * @param targetScore the targetScore to set
     */
    public void setTargetScore(Float targetScore) {
        int poss = computePossible(targetDirectives);
        int rec = computeReceived(targetDirectives);
        this.targetScore = (float)rec/poss;
    }

    /**
     * @return the productionScore
     */
    public Float getProductionScore() {
        int poss = computePossible(productionDirectives);
        int rec = computeReceived(productionDirectives);
        this.productionScore = (float)rec/poss;
        return this.productionScore;
    }

    /**
     * @param productionScore the productionScore to set
     */
    public void setProductionScore(Float productionScore) {
        int poss = computePossible(productionDirectives);
        int rec = computeReceived(productionDirectives);
        this.productionScore = (float)rec/poss;
    }

    /**
     * @return the environmentScore
     */
    public Float getEnvironmentScore() {
        int poss = computePossible(environmentDirectives);
        int rec = computeReceived(environmentDirectives);
        this.environmentScore = (float)rec/poss;
        return this.environmentScore;
    }

    /**
     * @param environmentScore the environmentScore to set
     */
    public void setEnvironmentScore(Float environmentScore) {
        int poss = computePossible(environmentDirectives);
        int rec = computeReceived(environmentDirectives);
        this.environmentScore = (float)rec/poss;
    }

    /**
     * @return the relationshipsScore
     */
    public Float getRelationshipsScore() {
        int poss = computePossible(relationshipsDirectives);
        int rec = computeReceived(relationshipsDirectives);
        this.relationshipsScore = (float)rec/poss;
        return this.relationshipsScore;
    }

    /**
     * @param relationshipsScore the relationshipsScore to set
     */
    public void setRelationshipsScore(Float relationshipsScore) {
        int poss = computePossible(relationshipsDirectives);
        int rec = computeReceived(relationshipsDirectives);
        this.relationshipsScore = (float)rec/poss;
    }

    /**
     * @return the totalScore
     */
    public Float getTotalScore() {
        int targetP = computePossible(targetDirectives);
        int productionP = computePossible(productionDirectives);
        int environmentP = computePossible(environmentDirectives);
        int relationshipsP = computePossible(relationshipsDirectives);
        int totalP = targetP + productionP + environmentP + relationshipsP;
        
        int targetR = computeReceived(targetDirectives);
        int productionR = computeReceived(productionDirectives);
        int environmentR = computeReceived(environmentDirectives);
        int relationshipsR = computeReceived(relationshipsDirectives);
        int totalR = targetR + productionR + environmentR + relationshipsR;
        this.totalScore = (float)totalR/totalP;
//        System.out.println("Target: "+Integer.toString(targetP));
//        System.out.println("Production: "+Integer.toString(productionP));
//        System.out.println("Environment: "+Integer.toString(environmentP));
//        System.out.println("Relationships: "+Integer.toString(relationshipsP));
//        System.out.println("Total: "+Integer.toString(totalP));
        return totalScore;
    }

    /**
     * @param totalScore the totalScore to set
     */
    public void setTotalScore(Float totalScore) {
         int targetP = computePossible(targetDirectives);
        int productionP = computePossible(productionDirectives);
        int environmentP = computePossible(environmentDirectives);
        int relationshipsP = computePossible(relationshipsDirectives);
        int totalP = targetP + productionP + environmentP + relationshipsP;
        
        int targetR = computeReceived(targetDirectives);
        int productionR = computeReceived(productionDirectives);
        int environmentR = computeReceived(productionDirectives);
        int relationshipsR = computeReceived(relationshipsDirectives);
        int totalR = targetR + productionR + environmentR + relationshipsR;
        this.totalScore = (float)totalR/totalP;
    }
   
    
}
